/**
 * @author phi
 */

/**
 * ベクトルクラス
 */
var Vector3 = (function(member) {
    
    var TempClass = function(){
        return new TempClass.prototype.creator();
    };
    
    TempClass.prototype = member;
    TempClass.prototype.creator = function(){ return this; };
    TempClass.prototype.creator.prototype = TempClass.prototype;
    
    return TempClass;
})({
    x : 0,
    y : 0,
    z : 0,
    
    set : function(x, y, z) {
        this.x = x || 0;
        this.y = y || 0;
        this.z = z || 0;
        return this;
    },
    add : function(v) {
        this.x += v.x;
        this.y += v.y;
        this.z += v.z;
        return this;
    },
    sub : function(v) {
        this.x -= v.x;
        this.y -= v.y;
        this.z -= v.z;
        return this;
    },
    mul : function(n) {
        this.x *= n;
        this.y *= n;
        this.z *= n;
        return this;
    },
    
    length : function() {
        return Math.sqrt( this.lengthSquare() );
    },

    lengthSquare : function() {
        return this.x * this.x + this.y * this.y + this.z * this.z;
    },
    
    normalize : function() {
        var len = this.length();
        this.x /= len;
        this.y /= len;
        this.z /= len;
        
        return this;
    },
    
    negative: function() {
        this.x *= -1;
        this.y *= -1;
        this.z *= -1;
        
        return this;
    },
    
    alert : function() { alert(this.x + ', ' + this.y + ', ' + this.z); }
});


Vector3.dot = function(v0, v1) {
    return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
};

Vector3.add = function(v0, v1)
{
    var v = Vector3();
    v.x = v0.x + v1.x;
    v.y = v0.y + v1.y;
    v.z = v0.z + v1.z;
    return v;
};

Vector3.sub = function(v0, v1)
{
    var v = Vector3();
    v.x = v0.x - v1.x;
    v.y = v0.y - v1.y;
    v.z = v0.z - v1.z;
    return v;
};

Vector3.mul = function(vec, n)
{
    var v = Vector3();
    v.x = vec.x * n;
    v.y = vec.y * n;
    v.z = vec.z * n;
    return v;
};

Vector3.negative = function(vec)
{
    var v = Vector3();
    v.x = -vec.x;
    v.y = -vec.y;
    v.z = -vec.z;
    return v;
}

/**
 * 反射処理
 * @param   v       現在のベクトル
 * @param   normal  反射対象となる壁の法線ベクトル
 */
Vector3.reflect = function(v, normal)
{
    var len = Vector3.dot(v, normal);
    var temp = Vector3.mul(normal, 2*len);
    
    return Vector3.sub(v, temp);
};


